//
//  Section.m
//  XLForm ( https://github.com/xmartlabs/XLForm )
//
//  Copyright (c) 2015 Xmartlabs ( http://xmartlabs.com )
//
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#import "XLForm.h"
#import "Section.h"
#import "UIView+XLFormAdditions.h"

@interface Section()
@property NSMutableArray * rows;
@end

@implementation Section

-(instancetype)init
{
    self = [super init];
    if (self){
        _rows = [NSMutableArray array];
        _sectionInsertMode = XLFormSectionInsertModeLastRow;
        _sectionOptions = XLFormSectionOptionNone;
        _title = nil;
        _footerTitle = nil;
        [self addObserver:self forKeyPath:@"rows"
                  options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld)
                  context:0];
    }
    return self;
}

+(nonnull instancetype)section:(void (^_Nullable)(Section * _Nonnull section))sectionConfig
{
    Section *result = [[Section alloc] init];
    BlockGoGo(sectionConfig,result);
    return result;
}

-(BOOL)isMultivaluedSection
{
    return (self.sectionOptions != XLFormSectionOptionNone);
}

-(void)addRow:(Row *)row
{
    NSUInteger index = ([self.rows count] > 0) ? [self.rows count] - 1 : 0;
    row.section = self;
    [self.rows insertObject:row atIndex:index];
}

-(void)addRow:(Row *)row afterRow:(Row *)afterRow
{
    NSUInteger afterRowIndex = [self.rows indexOfObject:afterRow];
    if (afterRowIndex != NSNotFound) {
        row.section = self;
        [self.rows insertObject:row atIndex:afterRowIndex +1];
    }
    else {
        [self addRow:row];
        return;
    }
}

-(void)addRow:(Row *)row beforeRow:(Row *)beforeRow
{
    NSUInteger beforeRowIndex = [self.rows indexOfObject:beforeRow];
    if (beforeRowIndex != NSNotFound) {
        row.section = self;
        [self.rows insertObject:row atIndex:beforeRowIndex];
    }
    else {
        [self addRow:row];
        return;
    }
}

-(void)removeRowAtIndex:(NSUInteger)index
{
    if (self.rows.count > index){
        [self.rows removeObjectAtIndex:index];
    }
}

-(void)removeRow:(Row *)row
{
    NSUInteger index = NSNotFound;
    if ((index = [self.rows indexOfObject:row]) != NSNotFound){
        [self removeRowAtIndex:index];
    }
}

- (void)moveRowAtIndexPath:(NSIndexPath *)sourceIndex toIndexPath:(NSIndexPath *)destinationIndex
{
    if ((sourceIndex.row < self.rows.count) && (destinationIndex.row < self.rows.count) && (sourceIndex.row != destinationIndex.row)){
        Row * row = [self.rows objectAtIndex:sourceIndex.row];
        [self.rows removeObjectAtIndex:sourceIndex.row];
        [self.rows insertObject:row atIndex:destinationIndex.row];
    }
}

-(void)dealloc
{
    @try {
        [self removeObserver:self forKeyPath:@"rows"];
    }
    @catch (NSException * __unused exception) {}
}

#pragma mark - KVO

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    if (!self.form.delegate) return;
    if ([keyPath isEqualToString:@"rows"]){
        if ([self.form.sections containsObject:self]){
            if ([[change objectForKey:NSKeyValueChangeKindKey] isEqualToNumber:@(NSKeyValueChangeInsertion)]){
                NSIndexSet * indexSet = [change objectForKey:NSKeyValueChangeIndexesKey];
                Row * formRow = [((Section *)object).rows objectAtIndex:indexSet.firstIndex];
                NSUInteger sectionIndex = [self.form.sections indexOfObject:object];
                [self.form.delegate rowHasBeenAdded:formRow atIndexPath:[NSIndexPath indexPathForRow:indexSet.firstIndex inSection:sectionIndex]];
            }
            else if ([[change objectForKey:NSKeyValueChangeKindKey] isEqualToNumber:@(NSKeyValueChangeRemoval)]){
                NSIndexSet * indexSet = [change objectForKey:NSKeyValueChangeIndexesKey];
                Row * removedRow = [[change objectForKey:NSKeyValueChangeOldKey] objectAtIndex:0];
                NSUInteger sectionIndex = [self.form.sections indexOfObject:object];
                [self.form.delegate rowHasBeenRemoved:removedRow atIndexPath:[NSIndexPath indexPathForRow:indexSet.firstIndex inSection:sectionIndex]];
            }
        }
    }
}
@end
